/*
 * LDIR
 * 
 * LDIR, a GPS cartography application built for Let's Do It Romania eco 
 * campaign.
 * Copyright (C) 2010 Genera Software <office@generasoftware.com>
 * 
 * http://generasoftware.com/
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 */
#include "AppUtils.h"

#include <bautils.h>
#include <caknfileselectiondialog.h>
#include <caknmemoryselectiondialog.h>
#include <eikenv.h>
#include <apgtask.h>
#include <utf.h>
#include <pathinfo.h>



CDesCArray* AppUtils::FindFilesL(const TDesC& aWildName, const TDesC& aScanDir, 
                                TFindFilesReturnType aReturnType)
{
   RFs fsSession;
   if (KErrNone != fsSession.Connect())
      return NULL;

   CDesCArrayFlat* filesResult = new (ELeave) CDesCArrayFlat(1);
   CleanupStack::PushL(filesResult);

   CDir* filesList = NULL;
   TFindFile fileFinder(fsSession);
   TInt err = fileFinder.FindWildByDir(aWildName, aScanDir, filesList);
   if (KErrNone == err)
   {
      CleanupStack::PushL(filesList);
      if (aReturnType == EFullPath)
      {
         TBuf<KMaxPath> fullName;
         for (TInt i = 0; i < filesList->Count(); i++)
         {
            fullName.Copy(aScanDir);
            fullName.Append((*filesList)[i].iName);
            filesResult->AppendL(fullName);
         }

      }
      else
      {
         for (TInt i = 0; i < filesList->Count(); i++)
            filesResult->AppendL((*filesList)[i].iName);
      }
      CleanupStack::PopAndDestroy(filesList);
   }

   fsSession.Close();

   CleanupStack::Pop(filesResult);
   return filesResult;
}


TInt AppUtils::GetFilesL(RFs& aFileSession, const TDesC& aPath, 
                        const TDesC& aExtension, CDesCArray* aFileList)
{
   TInt err = KErrNone;
   TBuf<KMaxPath> test = aPath;
   TFindFile file_finder(aFileSession); // 1
   TFileName fullName;
   CDir* file_list; // 2

   err = file_finder.FindWildByPath(aExtension, &aPath, file_list); // 3
   while (err==KErrNone)
   {
      TInt i;
      for (i=0; i<file_list->Count(); i++) // 4
      {
         TInt t;
         fullName = aPath;
         fullName.Append((*file_list)[i].iName);
         if (!(*file_list)[i].IsDir() && (aFileList->Find(fullName, t) != 0))
         {
            aFileList->AppendL(fullName);
         }
      }
      delete file_list; // 9
      err=file_finder.FindWild(file_list); // 10
   }

   file_list = 0;
   err = aFileSession.GetDir(aPath, KEntryAttMatchExclusive | KEntryAttDir, 
                              ESortByName, file_list);
   if (err == KErrNone)
   {
      for (TInt i = 0; i < file_list->Count(); ++i)
      {
         TFileName path = aPath;
         path += (*file_list)[i].iName;
         path += _L("\\");
         GetFilesL(aFileSession, path, aExtension, aFileList);
      }
   }
   delete file_list;

   return KErrNone;
}



TInt AppUtils::GetDriveL(TInt& aSelectedMemory, TDes& aDrivepath, 
                        const TDesC* aTitle, const TDesC* aLeftSoftkey, 
                        const TDesC* aRightSoftkey)
{
   TInt result = KErrNone;
   CAknMemorySelectionDialog* memoryDialog = 
      CAknMemorySelectionDialog::NewL(ECFDDialogTypeSave, EFalse);
   if (NULL != aTitle)
      memoryDialog->SetTitleL(*aTitle);
   if (NULL != aLeftSoftkey)
      memoryDialog->SetLeftSoftkeyL(*aLeftSoftkey);
   if (NULL != aRightSoftkey)
      memoryDialog->SetRightSoftkeyL(*aRightSoftkey);

   CAknMemorySelectionDialog::TMemory selectedMemory = CAknMemorySelectionDialog::EPhoneMemory;

   if (!memoryDialog->ExecuteL(selectedMemory))
      result = KErrCancel;
   else
      memoryDialog->GetMemories(selectedMemory, &aDrivepath, NULL);
   delete memoryDialog;
   aSelectedMemory = selectedMemory;
   return result;
}

TBool AppUtils::HasMemoryCardL(RFs& aFs)
{
   TInt result = KErrNotFound;
   result = BaflUtils::CheckFolder(aFs, PathInfo::MemoryCardRootPath());
   return result == KErrNone;
}

//////////////////////////////////////////////////////////////////////////
HBufC* AppUtils::EncodeUrlLC(const TDesC& aUrl)
{
   _LIT(KFormatCode, "%%%02x");

   if (!aUrl.Length())
   {
      return NULL;
   }

   TBufC<100> sDontEncode = 
      _L("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!-_.()*;/?:@&=+$[]!\\'()~");

   // Alloc to the maximum size of URL if every char are encoded
   HBufC* sEncoded = HBufC::NewLC(aUrl.Length() * 3);

   // Parse a the chars in the url
   for (TInt i=0; i < aUrl.Length(); ++i)
   {
      TChar cToFind = aUrl[i];
      if (KErrNotFound == sDontEncode.Locate(cToFind))
      {
         // Char not found encode it.
         sEncoded->Des().AppendFormat(KFormatCode, (TUint16)cToFind);
      }
      else
      {
         // char found just copy it
         sEncoded->Des().Append(cToFind);
      }
   }

   // Reallocate to the real size of the encoded url.
   sEncoded->ReAllocL(sEncoded->Length());
   return sEncoded;
}

//////////////////////////////////////////////////////////////////////////
HBufC8* AppUtils::EncodeUrlLC(const TDesC8& aUrl)
{

   if (!aUrl.Length())
   {
      return NULL;
   }

   // Alloc to the maximum size of URL if every char are encoded
   HBufC8* sEncoded = HBufC8::NewLC(aUrl.Length() * 3);
   HBufC* tempUnicodeBuffer = HBufC::NewLC(aUrl.Length() * 3);
   TPtr tempUniPtr = tempUnicodeBuffer->Des();
   CnvUtfConverter::ConvertToUnicodeFromUtf8(tempUniPtr, aUrl);
   HBufC* encodedUni = EncodeUrlLC(tempUniPtr);
   TPtr8 encodedPtr = sEncoded->Des();
   CnvUtfConverter::ConvertFromUnicodeToUtf8(encodedPtr, *encodedUni);
   CleanupStack::PopAndDestroy(2);
   return sEncoded;
}
